package com.blue.Impl.author;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.blue.common.constant.CommonConstant;
import com.blue.mapper.author.RoleMapper;
import com.blue.po.author.RoleMenuPO;
import com.blue.po.author.RolePO;
import com.blue.po.author.UserPO;
import com.blue.po.author.UserRolePO;
import com.blue.service.author.IRoleMenuService;
import com.blue.service.author.IRoleService;
import com.blue.service.author.IUserRoleService;
import com.blue.service.author.IUserService;
import com.github.yulichang.query.MPJQueryWrapper;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, RolePO> implements IRoleService {

    @Autowired
    private IUserService userService;
    @Autowired
    private IUserRoleService userRoleService;
    @Autowired
    private IRoleMenuService roleMenuService;

    @Override
    public Map<String, Object> relevanceUserInfo(String roleId) {
        Map<String, Object> resultMap = new HashMap<>();
        List<UserPO> allUsers = userService.list(new LambdaQueryWrapper<UserPO>()
                .select(UserPO::getUserId, UserPO::getUsername)
                .eq(UserPO::getStatus, CommonConstant.NORMAL));
        resultMap.put("allUsers", allUsers);
        MPJLambdaWrapper<UserPO> queryWrapper = JoinWrappers.lambda(UserPO.class)
                .select(UserPO::getUserId)
                .leftJoin(UserRolePO.class, UserRolePO::getUserId, UserPO::getUserId)
                .eq(UserRolePO::getRoleId, roleId);
        List<UserPO> includeUsers = userService.list(queryWrapper);
        List<String> userNoList = includeUsers.stream().map(UserPO::getUserId).collect(Collectors.toList());
        resultMap.put("includeUsers", userNoList);
        return resultMap;
    }

    @Override
    public void relevanceUser(Map<String, List<String>> map) {
        String roleId = map.keySet().iterator().next();
        userRoleService.remove(new LambdaQueryWrapper<UserRolePO>()
                .eq(UserRolePO::getRoleId, roleId));
        List<String> userIds = map.get(roleId);
        if (CollectionUtil.isNotEmpty(userIds)) {
            List<UserRolePO> userRolePOS = new ArrayList<>();
            userIds.forEach(item -> {
                UserRolePO userRolePO = new UserRolePO();
                userRolePO.setRoleId(roleId);
                userRolePO.setUserId(item);
                userRolePOS.add(userRolePO);
            });
            userRoleService.saveBatch(userRolePOS);
        }
    }

    @Override
    public void authorMenu(Map<String, List<String>> map) {
        String roleId = map.keySet().iterator().next();
        List<RoleMenuPO> menuList = roleMenuService.list(new LambdaQueryWrapper<RoleMenuPO>()
                .select(RoleMenuPO::getId)
                .eq(RoleMenuPO::getRoleId, roleId));
        if (CollectionUtil.isNotEmpty(menuList)) {
            List<String> ids = menuList.stream().map(RoleMenuPO::getId).collect(Collectors.toList());
            roleMenuService.removeBatchByIds(ids);
        }
        List<String> menuIds = map.get(roleId);
        List<RoleMenuPO> roleMenuPOS = new ArrayList<>();
        menuIds.forEach(item -> {
            RoleMenuPO roleMenuPO = new RoleMenuPO();
            roleMenuPO.setMenuId(item);
            roleMenuPO.setRoleId(roleId);
            roleMenuPOS.add(roleMenuPO);
        });
        roleMenuService.saveBatch(roleMenuPOS);
    }

    @Override
    @Transactional
    public void delete(List<String> ids) {
        this.removeBatchByIds(ids);
        userRoleService.remove(new LambdaQueryWrapper<UserRolePO>()
                .in(UserRolePO::getRoleId, ids));
    }
}
